package com.sugon.controller.util;

import java.math.BigDecimal;
import java.util.Arrays;

/**
 * 预测性维护分析算法
 */
public class SPFD {
    public SPFD() {
    }

    /**
     * 频谱算法
     * 输入与输出的长度相等
     * 输入为长度为2^n的double类型一维数组
     * 输出为长度为2^n的double类型一维数组（幅值）
     */
    public static double[] fft1(double[] data) {
        int nn = data.length;
        double[] absdata = new double[nn];
        double[] result = new double[2 * nn + 1];
        double[] realdata = new double[nn];
        double[] imagdata = new double[nn];
        int isign = 1;
        result[0] = 0.0D;

        int i;
        for (i = 1; i < nn + 1; ++i) {
            result[2 * i - 1] = data[i - 1];
            result[2 * i] = 0.0D;
        }

        int n = 2 * nn;
        int j = 1;

        int m;
        double tempr;
        double tempi;
        for (i = 1; i <= n; i += 2) {
            if (j > i) {
                tempr = result[j];
                tempi = result[j + 1];
                result[j] = result[i];
                result[j + 1] = result[i + 1];
                result[i] = tempr;
                result[i + 1] = tempi;
            }

            for (m = n / 2; m >= 2 && j > m; m /= 2) {
                j -= m;
            }

            j += m;
        }

        int istep;
        for (int mmax = 2; n > mmax; mmax = istep) {
            istep = 2 * mmax;
            double theta = 6.28318530717959D / (double) (isign * mmax);
            double wpr = -2.0D * Math.sin(0.5D * theta) * Math.sin(0.5D * theta);
            double wpi = Math.sin(theta);
            double wr = 1.0D;
            double wi = 0.0D;

            for (m = 1; m <= mmax; m += 2) {
                for (i = m; i <= n; i += istep) {
                    j = i + mmax;
                    tempr = wr * result[j] - wi * result[j + 1];
                    tempi = wr * result[j + 1] + wi * result[j];
                    result[j] = result[i] - tempr;
                    result[j + 1] = result[i + 1] - tempi;
                    result[i] += tempr;
                    result[i + 1] += tempi;
                }

                double wtemp = wr;
                wr += wr * wpr - wi * wpi;
                wi += wi * wpr + wtemp * wpi;
            }
        }

        for (i = 1; i <= n; ++i) {
            result[i] /= (double) nn;
            if (i % 2 == 0) {
                result[i] = -1.0D * result[i];
            }
        }

        for (i = 1; i < nn + 1; ++i) {
            realdata[i - 1] = result[2 * i - 1];
            imagdata[i - 1] = result[2 * i];
        }

        for (i = 0; i < nn; ++i) {
            absdata[i] = 2.0D * Math.sqrt(realdata[i] * realdata[i] + imagdata[i] * imagdata[i]);
        }

        return absdata;
    }

    public static double[] fft2(double[] data) {
        int nn = data.length;
        double[] result = new double[2 * nn + 1];
        double[] result1 = new double[2 * nn + 1];
        double[] realdata = new double[nn];
        double[] imagdata = new double[nn];
        int isign = 1;
        result[0] = 0.0D;

        int i;
        for (i = 1; i < nn + 1; ++i) {
            result[2 * i - 1] = data[i - 1];
            result[2 * i] = 0.0D;
        }

        int n = 2 * nn;
        int j = 1;

        int m;
        double tempr;
        double tempi;
        for (i = 1; i <= n; i += 2) {
            if (j > i) {
                tempr = result[j];
                tempi = result[j + 1];
                result[j] = result[i];
                result[j + 1] = result[i + 1];
                result[i] = tempr;
                result[i + 1] = tempi;
            }

            for (m = n / 2; m >= 2 && j > m; m /= 2) {
                j -= m;
            }

            j += m;
        }

        int istep;
        for (int mmax = 2; n > mmax; mmax = istep) {
            istep = 2 * mmax;
            double theta = 6.28318530717959D / (double) (isign * mmax);
            double wpr = -2.0D * Math.sin(0.5D * theta) * Math.sin(0.5D * theta);
            double wpi = Math.sin(theta);
            double wr = 1.0D;
            double wi = 0.0D;

            for (m = 1; m <= mmax; m += 2) {
                for (i = m; i <= n; i += istep) {
                    j = i + mmax;
                    tempr = wr * result[j] - wi * result[j + 1];
                    tempi = wr * result[j + 1] + wi * result[j];
                    result[j] = result[i] - tempr;
                    result[j + 1] = result[i + 1] - tempi;
                    result[i] += tempr;
                    result[i + 1] += tempi;
                }

                double wtemp = wr;
                wr += wr * wpr - wi * wpi;
                wi += wi * wpr + wtemp * wpi;
            }
        }

        for (i = 1; i <= n; ++i) {
            result[i] /= (double) nn;
            if (i % 2 == 0) {
                result[i] = -1.0D * result[i];
            }
        }

        for (i = 1; i < nn + 1; ++i) {
            realdata[i - 1] = result[2 * i - 1];
            imagdata[i - 1] = result[2 * i];
        }

        System.arraycopy(realdata, 0, result1, 0, nn);
        System.arraycopy(imagdata, 0, result1, nn, nn);
        return result1;
    }

    /**
     * 滤波算法
     * n为滤波器的阶数，fln通带上限截止频率、 fhn为通带上限截止频率，fs为采样
     */
    public static double[] firwin(int n, double fln, double fhn, double fs, int band) {
        double wc2 = 0.0D;
        double beta = 3.4D;
        double[] h = new double[n + 1];
        double pi = 4.0D * Math.atan(1.0D);
        int n2;
        boolean midd;
        if (n % 2 == 0) {
            n2 = n / 2 - 1;
            midd = true;
        } else {
            n2 = n / 2;
            midd = false;
        }

        double delay = (double) n / 2.0D;
        double wc1 = 2.0D * pi * fln / fs;
        if (band >= 3) {
            wc2 = 2.0D * pi * fhn / fs;
        }

        double s;
        int i;
        switch (band) {
            case 1:
                for (i = 0; i <= n2; ++i) {
                    s = (double) i - delay;
                    h[i] = Math.sin(wc1 * s) / (pi * s) * Window(n + 1, i, beta);
                    h[n - i] = h[i];
                }

                if (midd) {
                    h[n / 2] = wc1 / pi;
                }
                break;
            case 2:
                for (i = 0; i <= n2; ++i) {
                    s = (double) i - delay;
                    h[i] = (Math.sin(pi * s) - Math.sin(wc1 * s)) / (pi * s);
                    h[i] *= Window(n + 1, i, beta);
                    h[n - i] = h[i];
                }

                if (midd) {
                    h[n / 2] = 1.0D - wc1 / pi;
                }
                break;
            case 3:
                for (i = 0; i <= n2; ++i) {
                    s = (double) i - delay;
                    h[i] = (Math.sin(s * wc2) - Math.sin(wc1 * s)) / (pi * s);
                    h[i] *= Window(n + 1, i, beta);
                    h[n - i] = h[i];
                }

                if (midd) {
                    h[n / 2] = (wc2 - wc1) / pi;
                }
                break;
            case 4:
                for (i = 0; i <= n2; ++i) {
                    s = (double) i - delay;
                    h[i] = (Math.sin(wc1 * s) + Math.sin(pi * s) - Math.sin(wc2 * s)) / (pi * s);
                    h[i] *= Window(n + 1, i, beta);
                    h[n - i] = h[i];
                }

                if (midd) {
                    h[n / 2] = (wc1 + pi - wc2) / pi;
                }
        }

        return h;
    }

    public static double Window(int K, int M, double G) {
        double b1 = bessel0(G);
        double a = 2.0D * (double) M / (double) (K - 1) - 1.0D;
        double a2 = a * a;
        double betal = G * Math.sqrt(1.0D - a2);
        double b2 = bessel0(betal);
        double Window1 = b2 / b1;
        return Window1;
    }

    public static double bessel0(double J) {
        double y = J / 2.0D;
        double d = 1.0D;
        double bessel = 1.0D;

        for (int T = 1; T <= 25; ++T) {
            d = d * y / (double) T;
            double d2 = d * d;
            bessel += d2;
            if (d2 < bessel * 1.0E-8D) {
                break;
            }
        }

        return bessel;
    }

    public static double[] filter(double[] b, double[] a, double[] xn) {
        int nn = xn.length;
        double[] y = new double[nn];
        int k = b.length - 1;
        a[0] = 0.0D;
        double[] temx = new double[nn + k];

        int i;
        for (i = 0; i <= k - 1; ++i) {
            temx[i] = 0.0D;
        }

        for (i = k; i <= nn - 1 + k; ++i) {
            temx[i] = xn[i - k];
        }

        double[] temy = new double[nn + k];

        for (i = 0; i <= nn - 1 + k; ++i) {
            temy[i] = 0.0D;
        }

        for (i = k; i <= nn - 1 + k; ++i) {
            for (int j = 0; j <= k; ++j) {
                temy[i] += b[j] * temx[i - j] - a[j] * temy[i - j];
            }
        }

        for (i = 0; i <= nn - 1; ++i) {
            y[i] = temy[i + k];
        }

        return y;
    }

    /**
     * 自相关算法
     * data为长度为n的double类型的一维数组（信号）
     * freq为int类型的单个数值（采样频率）
     */
    public static double[] autoCorrelation(double[] data, int freq) {
        int length = data.length;
        double[] x_autoCorr = new double[2 * length];

        int i;
        for (i = 0; i < length; ++i) {
            x_autoCorr[i] = (double) (i + 1) / (double) freq;
        }

        for (i = length; i < 2 * length - 1; ++i) {
            int ii = i - length;

            for (int j = 0; j < length - ii; ++j) {
                x_autoCorr[i] += data[j] * data[ii + j] / (double) (length - ii);
            }
        }

        return x_autoCorr;
    }

    /**
     * 互相关分析
     * data1、data2均为长度为n的double类型的一维数组（两段振动信号）
     * freq为int类型的单个数值（采样频率）
     */
    public static double[] crossCorrelation(double[] data1, double[] data2, int freq) {
        int length = data1.length;
        double[] x_crossCorr = new double[2 * length];

        int i;
        for (i = 0; i < length; ++i) {
            x_crossCorr[i] = (double) (i + 1) / (double) freq;
        }

        for (i = length; i < 2 * length - 4; ++i) {
            int ii = i - length;

            for (int j = 0; j < length - ii; ++j) {
                x_crossCorr[i] += data1[j] * data2[ii + j] / (double) (length - ii);
            }
        }

        return x_crossCorr;
    }

    /**
     * 轴心位置计算
     * X,Y皆为长度为n的一维数组（信号）；offx,offy皆为单个数值（补偿量）
     * k为单个数值（电压信号到距离信号的转换关系）
     */
    public static double[] axisposition(double[] datax, double[] datay, int offx, int offy, double k) {
        double[] result = new double[2];
        int n = datax.length;
        double tempx = 0.0D;
        double tempy = 0.0D;

        for (int i = 0; i < n; ++i) {
            tempx = datax[i];
            tempy = datay[i];
        }

        result[0] = (k * tempx / (double) n + (double) offx) / Math.sqrt(0.5D) - (k * tempy / (double) n + (double) offy) / Math.sqrt(0.5D);
        result[1] = (k * tempx / (double) n + (double) offx) / Math.sqrt(0.5D) + (k * tempy / (double) n + (double) offy) / Math.sqrt(0.5D);
        return result;
    }

    /**
     * 轴心轨迹计算
     * 输入皆为长度为n的一维数组（信号）；offx,offy皆为单个数值（补偿量）；k为单个数值（电压信号到距离信号的转换关系）
     * 输出为长度为2的一维数组
     */
    public static double[] axisorbit(double[] datax, double[] datay, int offx, int offy, double k) {
        double[] result = new double[2 * datax.length];
        int n = datax.length;

        for (int i = 0; i < n; ++i) {
            result[i] = k * datax[i] + (double) offx;
            result[i + n] = k * datay[i] + (double) offy;
        }

        return result;
    }

    /**
     * 伯德图算法
     * X为一维数组（信号）
     * f为单个数值（采样频率）
     */
    public static double[] fftbode(double[] data) {
        int nn = data.length;
        double[] result = new double[2 * nn + 1];
        double[] result1 = new double[2 * nn + 1];
        double[] realdata = new double[nn];
        double[] imagdata = new double[nn];
        int isign = 1;
        result[0] = 0.0D;

        int i;
        for (i = 1; i < nn + 1; ++i) {
            result[2 * i - 1] = data[i - 1];
            result[2 * i] = 0.0D;
        }

        int n = 2 * nn;
        int j = 1;

        int m;
        double tempr;
        double tempi;
        for (i = 1; i <= n; i += 2) {
            if (j > i) {
                tempr = result[j];
                tempi = result[j + 1];
                result[j] = result[i];
                result[j + 1] = result[i + 1];
                result[i] = tempr;
                result[i + 1] = tempi;
            }

            for (m = n / 2; m >= 2 && j > m; m /= 2) {
                j -= m;
            }

            j += m;
        }

        int istep;
        for (int mmax = 2; n > mmax; mmax = istep) {
            istep = 2 * mmax;
            double theta = 6.28318530717959D / (double) (isign * mmax);
            double wpr = -2.0D * Math.sin(0.5D * theta) * Math.sin(0.5D * theta);
            double wpi = Math.sin(theta);
            double wr = 1.0D;
            double wi = 0.0D;

            for (m = 1; m <= mmax; m += 2) {
                for (i = m; i <= n; i += istep) {
                    j = i + mmax;
                    tempr = wr * result[j] - wi * result[j + 1];
                    tempi = wr * result[j + 1] + wi * result[j];
                    result[j] = result[i] - tempr;
                    result[j + 1] = result[i + 1] - tempi;
                    result[i] += tempr;
                    result[i + 1] += tempi;
                }
                double wtemp = wr;
                wr += wr * wpr - wi * wpi;
                wi += wi * wpr + wtemp * wpi;
            }
        }

        for (i = 1; i <= n; ++i) {
            result[i] = 2.0D * result[i] / (double) nn;
            if (i % 2 == 0) {
                result[i] = -1.0D * result[i];
            }
        }

        for (i = 1; i < nn + 1; ++i) {
            realdata[i - 1] = result[2 * i - 1];
            imagdata[i - 1] = -result[2 * i];
        }

        System.arraycopy(realdata, 0, result1, 0, nn);
        System.arraycopy(imagdata, 0, result1, nn, nn);
        return result1;
    }

    public static int ntom(int m) {
        int n;
        for (n = 2; n < m; n *= 2) {
        }

        n /= 2;
        return n;
    }

    public static double[] max(double[] data) {
        double[] result = new double[2];
        double max = 0.0D;
        int k = 0;
        int n = data.length / 2;

        for (int i = 1; i < n; ++i) {
            double add = data[i] * data[i] + data[i + n] * data[i + n];
            if (add > max) {
                max = add;
                k = i;
            }
        }

        result[0] = Math.sqrt(max);
        result[1] = (double) k;
        return result;
    }

    public static double[] bode(double[] data, int f) {
        double[] result = new double[3];
        double[] maxresult = new double[2];
        int m = data.length;
        int n = ntom(m);
        double[] tempdata = new double[n];
        tempdata = fftbode(data);
        maxresult = max(tempdata);
        int k = (int) maxresult[1];
        result[0] = Math.atan2(tempdata[k + n], tempdata[k]);
        result[1] = 30.0 * f * k / n;
        result[2] = maxresult[0];
        return result;
    }

    public static double peak(double[] data) {
        double result = 0.0D;
        double min = 100.0D;
        double max = -100.0D;
        int n = data.length;

        for (int i = 0; i < n; ++i) {
            if (data[i] < min) {
                min = data[i];
            }

            if (data[i] > max) {
                max = data[i];
            }
        }

        result = max - min;
        return result;
    }

    public static double[] log_log(double[] datax, double[] datay) {
        double[] result = new double[2 * datax.length];
        int n = datax.length;

        for (int i = 0; i < n; ++i) {
            result[i] = Math.log(datax[i]);
            result[i + n] = Math.log(datay[i]);
        }

        return result;
    }

    public static double[] log_lin(double[] datax, double[] datay) {
        double[] result = new double[2 * datax.length];
        int n = datax.length;

        for (int i = 0; i < n; ++i) {
            result[i] = Math.log(datax[i]);
            result[i + n] = datay[i];
        }

        return result;
    }

    public static double[] lin_log(double[] datax, double[] datay) {
        double[] result = new double[2 * datax.length];
        int n = datax.length;

        for (int i = 0; i < n; ++i) {
            result[i] = datax[i];
            result[i + n] = Math.log(datay[i]);
        }

        return result;
    }

    public static double[] lin_lin(double[] datax, double[] datay) {
        double[] result = new double[2 * datax.length];
        int n = datax.length;

        for (int i = 0; i < n; ++i) {
            result[i] = datax[i];
            result[i + n] = datay[i];
        }

        return result;
    }

    public static double[] xy_change(double[] datax, double[] datay) {
        double[] result = new double[2 * datax.length];
        int n = datax.length;

        for (int i = 0; i < n; ++i) {
            result[i] = datax[i] / Math.sqrt(0.5D) - datay[i] / Math.sqrt(0.5D);
            result[i + n] = datax[i] / Math.sqrt(0.5D) + datay[i] / Math.sqrt(0.5D);
        }

        return result;
    }

    public static String FaultChoose(double[] C, String D17, String D18) {
        String[] D = new String[17];
        String De = "确定性故障：";
        String Ude = "可能存在故障：";

        int i;
        for (i = 0; i < 17; ++i) {
            D[i] = "";
        }
        BigDecimal a = BigDecimal.valueOf(0.1);
        if (a.compareTo(BigDecimal.valueOf(C[0])) == 0) {
            D[0] = "油膜涡动,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[1])) == 0) {
            D[1] = "转子迟滞,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[2])) == 0) {
            D[2] = "质量不平衡,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[3])) == 0) {
            D[3] = "碰摩故障,";
        }

        double var10000 = C[4];
        if (a.compareTo(BigDecimal.valueOf(C[5])) == 0) {
            D[5] = "部件松动,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[13])) == 0) {
            D[6] = "质量不平衡,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[14])) == 0) {
            D[7] = "部件松动,";
            C[15] = 0.0D;
        }

        De = De + D17;
        De = De + D18;

        for (i = 0; i < 8; ++i) {
            De = De + D[i];
        }

        if (De.equals("确定性故障：")) {
            De = "确定性故障:无";
        }

        if (De.endsWith(",")) {
            De = De.substring(0, De.length() - 1);
        }

        if (a.compareTo(BigDecimal.valueOf(C[6])) == 0) {
            D[8] = "热不稳定性,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[7])) == 0) {
            D[9] = "重力临界或者非对称轴,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[8])) == 0) {
            D[10] = "不对中或耦合自锁,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[9])) == 0) {
            D[11] = "轴端部弯曲,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[10])) == 0) {
            D[12] = "轴中心弯曲,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[11])) == 0) {
            D[13] = "结构共振,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[12])) == 0) {
            D[14] = "轴裂纹,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[15])) == 0) {
            D[15] = "部件松动,";
        }

        if (a.compareTo(BigDecimal.valueOf(C[16])) == 0) {
            D[16] = "碰摩故障,";
        }

        for (i = 8; i < 17; ++i) {
            Ude = Ude + D[i];
        }

        if (Ude.equals("可能存在故障：")) {
            Ude = "可能存在故障：无";
        }

        if (Ude.endsWith(",")) {
            Ude = Ude.substring(0, Ude.length() - 1);
        }

        String result = De + "    " + Ude;
        return result;
    }

    public static double[] SignalDiscrete(double[] S, double FS, double OPF, double INF) {
        int cutoff1 = 0;
        int cutoff2 = 0;
        int cut = 0;
        double[] A_fre = new double[S.length];
        double[] fre = new double[S.length / 2];
        int num = fre.length;
        double[] Vector = new double[12];
        A_fre = fft1(S);

        int i;
        for (i = 0; i < num; ++i) {
            fre[i] = FS * (double) i / (double) num / 2.0D;
        }

        for (i = 0; i < num; ++i) {
            if (fre[i] > OPF - INF) {
                cutoff1 = i - 1;
                break;
            }
        }

        for (i = 0; i < num; ++i) {
            if (fre[i] > OPF + INF) {
                cutoff2 = i;
                break;
            }
        }

        double[] AX1 = new double[cutoff2 - cutoff1 + 1];

        for (i = 0; i < cutoff2 - cutoff1 + 1; ++i) {
            AX1[i] = A_fre[i + cutoff1];
        }

        double X1 = getMax(AX1);
        double[] FLAX1 = new double[cutoff1];
        double[] BLAX1 = new double[num - cutoff2 - 1];

        for (i = 0; i < cutoff1; ++i) {
            FLAX1[i] = A_fre[i];
        }

        for (i = 0; i < num - cutoff2 - 1; ++i) {
            BLAX1[i] = A_fre[i + cutoff2 + 1];
        }

        double FX1 = getMax(FLAX1);
        double BX1 = getMax(BLAX1);

        for (i = 0; i < num - cutoff2 - 1; ++i) {
            if (fre[i] >= OPF / 2.0D) {
                cut = i;
                break;
            }
        }

        double[] AX0Td5 = new double[cut + 1];

        for (i = 0; i < cut + 1; ++i) {
            AX0Td5[i] = A_fre[i];
        }

        double X0Td5 = getMax(AX0Td5);
        double Xd5 = findPeak(fre, A_fre, OPF, INF, 0.5D, 0.5D, num);
        double Xd65Td85 = findPeak(fre, A_fre, OPF, INF, 0.65D, 0.85D, num);
        double X2 = findPeak(fre, A_fre, OPF, INF, 2.0D, 2.0D, num);
        double X3 = findPeak(fre, A_fre, OPF, INF, 3.0D, 3.0D, num);
        double X4 = findPeak(fre, A_fre, OPF, INF, 4.0D, 4.0D, num);
        double X5 = findPeak(fre, A_fre, OPF, INF, 5.0D, 5.0D, num);
        double X6 = findPeak(fre, A_fre, OPF, INF, 6.0D, 6.0D, num);
        double X7 = findPeak(fre, A_fre, OPF, INF, 7.0D, 7.0D, num);
        Vector[0] = FX1;
        Vector[1] = BX1;
        Vector[2] = X1;
        Vector[3] = X0Td5;
        Vector[4] = Xd5;
        Vector[5] = Xd65Td85;
        Vector[6] = X2;
        Vector[7] = X3;
        Vector[8] = X4;
        Vector[9] = X5;
        Vector[10] = X6;
        Vector[11] = X7;
        double[] result = new double[]{FX1, BX1, X1, X0Td5, Xd5, Xd65Td85, X2, X3, X4, X5, X6, X7};
        return result;
    }

    public static double getMax(double[] arr) {
        double max = arr[0];

        for (int i = 1; i < arr.length; ++i) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }

        return max;
    }

    public static double findPeak(double[] fre, double[] A_fre, double OPF, double INF, double ffn1, double ffn2, int num) {
        int cutoff1 = 0;
        int cutoff2 = 0;

        int i;
        for (i = 0; i < num; ++i) {
            if (fre[i] > ffn1 * OPF - INF) {
                cutoff1 = i - 1;
                break;
            }
        }

        for (i = 0; i < num; ++i) {
            if (fre[i] > ffn2 * OPF + INF) {
                cutoff2 = i;
                break;
            }
        }

        double[] tempAXN = new double[cutoff2 - cutoff1 + 1];

        for (i = 0; i < cutoff2 - cutoff1 + 1; ++i) {
            tempAXN[i] = A_fre[i + cutoff1];
        }

        double RstPeak = getMax(tempAXN);
        return RstPeak;
    }

    public static String faultdiagnosis(double[] datax, double[] datay, double[] dataxw, double[] datayw, double f, double[] par, String[] choice, double current, double[] par1) {
        int w = dataxw.length;
        String D17 = "";
        String D18 = "";
        double wx = 0.0D;
        double wy = 0.0D;

        for (int i = 0; i < w; ++i) {
            wx += dataxw[i] * dataxw[i];
            wy += datayw[i] * datayw[i];
        }

        if (wx != 0.0D && Math.sqrt(wy / wx) > 2.5D) {
            D17 = "轴承座松动（支撑刚度不足），";
        }

        if (current > 0.1D) {
            D18 = "转子转动中心与轴瓦中心偏移";
        }

        String D = "";
        double[] data1 = new double[12];
        double[] data2 = new double[12];
        double[] data3 = new double[12];
        double[] data4 = new double[12];
        double[] C = new double[12];
        double OPF = par[12];
        double INF = par[13];
        data1 = SignalDiscrete(datax, f, OPF, INF);
        data2 = SignalDiscrete(datay, f, OPF, INF);
        data3 = SignalDiscrete(dataxw, f, OPF, INF);
        data4 = SignalDiscrete(datayw, f, OPF, INF);
        double yuzhi1 = par1[0];
        double yuzhi2 = par1[1];
        boolean flag1 = data1[2] < yuzhi1 && data2[2] < yuzhi1 && data1[6] < yuzhi1 && data2[6] < yuzhi1;
        boolean flag2 = data3[2] < yuzhi2 && data4[2] < yuzhi2 && data3[6] < yuzhi2 && data4[6] < yuzhi2;
        if (flag1 && flag2) {
            D = "确定性故障:无    可能存在故障：无";
        } else {
            C = FaultJudge(data1, data1, data2, par, choice);
            boolean FT = IsFault(data1, data1, data2, par, choice);
           /* if (FT) {
                D = FaultChoose(C, D17, D18);
            } else {*/
            D = FaultChoose(C, D17, D18);
            /* }*/
        }

        return D;
    }

    public static double[] FaultJudge(double[] Vector, double[] Vector1, double[] Vector2, double[] ParFault1, String[] ParFault2) {
        double[] C = new double[17];
        double[] Tem = new double[12];
        double YMWDrate = ParFault1[0];
        double ZZCZrate = ParFault1[1];
        double HDZCratedeta = ParFault1[2];
        double BJSDrate = ParFault1[3];
        double XBrate = ParFault1[4];
        double PMrate = ParFault1[5];
        double Rate = ParFault1[6];
        double JGGZrate = ParFault1[7];
        double ZLWrate = ParFault1[8];
        double A_ZCfrequency = ParFault1[9];
        double BPHrate = ParFault1[10];
        double ZCrate = ParFault1[11];
        String XBmax = ParFault2[0];
        String ZZLX = ParFault2[1];
        String ZXGJ = ParFault2[2];

        for (int i = 0; i < 12; ++i) {
            Tem[i] = Vector[i] / Vector[2];
        }

        if (Vector1[2] / A_ZCfrequency > BPHrate) {
            C[13] = 1.0D;
        }

        if (Tem[3] >= YMWDrate) {
            C[0] = 1.0D;
        }

        if (Tem[5] >= ZZCZrate) {
            C[1] = 1.0D;
        }

        if (Tem[6] < Rate) {
            if (Tem[4] > 1.0D - HDZCratedeta && Tem[4] < 1.0D + HDZCratedeta) {
                C[4] = 1.0D;
            }

            if (Vector1[2] / Vector2[2] > BJSDrate || Vector1[2] / Vector2[2] < 1.0D / BJSDrate) {
                C[14] = 1.0D;
            }

            label238:
            {
                label233:
                {
                    label203:
                    switch (XBmax.hashCode()) {
                        case 724312:
                            if (!XBmax.equals("4倍频")) {
                                return C;
                            }

                            if (Tem[7] > XBrate && Tem[8] > XBrate) {
                                C[15] = 1.0D;
                                switch (ZZLX.hashCode()) {
                                    case 650963825:
                                        if (!ZZLX.equals("刚性转子")) {
                                            break label203;
                                        }

                                        if (ZXGJ.equals("存在内凹")) {
                                            C[3] = 1.0D;
                                        } else {
                                            C[16] = 1.0D;
                                        }
                                        break;
                                    case 780793003:
                                        if (!ZZLX.equals("挠性转子")) {
                                            break label203;
                                        }
                                        break;
                                    default:
                                        break label203;
                                }

                                if (ZXGJ.equals("多环嵌套")) {
                                    C[3] = 1.0D;
                                } else if (Tem[4] > PMrate) {
                                    C[3] = 1.0D;
                                } else {
                                    C[16] = 1.0D;
                                }
                            } else {
                                C[6] = 1.0D;
                            }
                            break;
                        case 725273:
                            if (!XBmax.equals("5倍频")) {
                                return C;
                            }
                            break;
                        case 726234:
                            if (!XBmax.equals("6倍频")) {
                                return C;
                            }
                            break label233;
                        case 727195:
                            if (!XBmax.equals("7倍频")) {
                                return C;
                            }
                            break label238;
                        default:
                            return C;
                    }

                    if (Tem[7] > XBrate && Tem[8] > XBrate && Tem[9] > XBrate) {
                        label182:
                        {
                            C[15] = 1.0D;
                            switch (ZZLX.hashCode()) {
                                case 650963825:
                                    if (!ZZLX.equals("刚性转子")) {
                                        break label182;
                                    }

                                    if (ZXGJ.equals("存在内凹")) {
                                        C[3] = 1.0D;
                                    } else {
                                        C[16] = 1.0D;
                                    }
                                    break;
                                case 780793003:
                                    if (!ZZLX.equals("挠性转子")) {
                                        break label182;
                                    }
                                    break;
                                default:
                                    break label182;
                            }

                            if (ZXGJ.equals("多环嵌套")) {
                                C[3] = 1.0D;
                            } else if (Tem[4] > PMrate) {
                                C[3] = 1.0D;
                            } else {
                                C[16] = 1.0D;
                            }
                        }
                    } else {
                        C[6] = 1.0D;
                    }
                }

                if (Tem[7] > XBrate && Tem[8] > XBrate && Tem[9] > XBrate && Tem[10] > XBrate) {
                    label167:
                    {
                        C[15] = 1.0D;
                        switch (ZZLX.hashCode()) {
                            case 650963825:
                                if (!ZZLX.equals("刚性转子")) {
                                    break label167;
                                }

                                if (ZXGJ.equals("存在内凹")) {
                                    C[3] = 1.0D;
                                } else {
                                    C[16] = 1.0D;
                                }
                                break;
                            case 780793003:
                                if (!ZZLX.equals("挠性转子")) {
                                    break label167;
                                }
                                break;
                            default:
                                break label167;
                        }

                        if (ZXGJ.equals("多环嵌套")) {
                            C[3] = 1.0D;
                        } else if (Tem[4] > PMrate) {
                            C[3] = 1.0D;
                        } else {
                            C[16] = 1.0D;
                        }
                    }
                } else {
                    C[6] = 1.0D;
                }
            }

            if (Tem[7] > XBrate && Tem[8] > XBrate && Tem[9] > XBrate && Tem[10] > XBrate && Tem[11] > XBrate) {
                C[15] = 1.0D;
                switch (ZZLX.hashCode()) {
                    case 650963825:
                        if (!ZZLX.equals("刚性转子")) {
                            return C;
                        }

                        if (ZXGJ.equals("存在内凹")) {
                            C[3] = 1.0D;
                        } else {
                            C[16] = 1.0D;
                        }
                        break;
                    case 780793003:
                        if (!ZZLX.equals("挠性转子")) {
                            return C;
                        }
                        break;
                    default:
                        return C;
                }

                if (ZXGJ.equals("多环嵌套")) {
                    C[3] = 1.0D;
                } else if (Tem[4] > PMrate) {
                    C[3] = 1.0D;
                } else {
                    C[16] = 1.0D;
                }
            } else {
                C[6] = 1.0D;
            }
        } else if (1.0D / Tem[6] < Rate) {
            C[7] = 1.0D;
        } else {
            if (ZXGJ.equals("8字轨迹")) {
                C[8] = 1.0D;
            }

            if (Tem[6] >= JGGZrate) {
                C[11] = 1.0D;
            }

            if (1.0D / Tem[6] < ZLWrate) {
                C[12] = 1.0D;
            }

            if (Tem[6] > 1.0D) {
                C[9] = 1.0D;
            } else {
                C[10] = 1.0D;
            }
        }

        return C;
    }

    public static boolean IsFault(double[] Vector, double[] Vector1, double[] Vector2, double[] ParFault1, String[] ParFault2) {
        boolean IsFaultFlag = false;
        double YMWDrate = ParFault1[0];
        double ZZCZrate = ParFault1[1];
        double HDZCratedeta = ParFault1[2];
        double BJSDrate = ParFault1[3];
        double XBrate = ParFault1[4];
        double PMrate = ParFault1[5];
        double Rate = ParFault1[6];
        double JGGZrate = ParFault1[7];
        double ZLWrate = ParFault1[8];
        double A_ZCfrequency = ParFault1[9];
        double BPHrate = ParFault1[10];
        double ZCrate = ParFault1[11];
        if (Vector1[2] / A_ZCfrequency <= BPHrate && Vector1[0] / Vector1[2] < YMWDrate && Vector1[1] / Vector1[2] < ZZCZrate) {
            IsFaultFlag = false;
        } else {
            IsFaultFlag = true;
        }

        return IsFaultFlag;
    }

    public static double[] fht(double[] x, int n) {
        int m = 1;
        int j = 1;

        int i;
        for (i = 1; i < 16; ++i) {
            m = i;
            j *= 2;
            if (j == n) {
                break;
            }
        }

        int n1 = n - 1;
        j = 0;

        int k;
        double t;
        for (i = 0; i < n1; ++i) {
            if (i < j) {
                t = x[j];
                x[j] = x[i];
                x[i] = t;
            }

            for (k = n / 2; k < j + 1; k /= 2) {
                j -= k;
            }

            j += k;
        }

        for (i = 0; i < n; i += 2) {
            t = x[i];
            x[i] = t + x[i + 1];
            x[i + 1] = t - x[i + 1];
        }

        int n2 = 1;

        for (k = 2; k <= m; ++k) {
            int n4 = n2;
            n2 += n2;
            n1 = n2 + n2;
            double e = 6.283185307179586D / (double) n1;

            for (j = 0; j < n; j += n1) {
                int l2 = j + n2;
                int l3 = j + n4;
                int l4 = l2 + n4;
                t = x[j];
                x[j] = t + x[l2];
                x[l2] = t - x[l2];
                t = x[l3];
                x[l3] = t + x[l4];
                x[l4] = t - x[l4];
                double a = e;

                for (i = 1; i < n4; ++i) {
                    int l1 = j + i;
                    l2 = j - i + n2;
                    l3 = l1 + n2;
                    l4 = l2 + n2;
                    double c = Math.cos(a);
                    double s = Math.sin(a);
                    double t1 = x[l3] * c + x[l4] * s;
                    double t2 = x[l3] * s - x[l4] * c;
                    a = (double) (i + 1) * e;
                    t = x[l1];
                    x[l1] = t + t1;
                    x[l3] = t - t1;
                    t = x[l2];
                    x[l2] = t + t2;
                    x[l4] = t - t2;
                }
            }
        }

        return x;
    }

    /**
     * 希尔伯特变换
     * x为一维数组(信号)，double[]
     **/
    public static double[] hilbtb(double[] x) {
        int n = ntom1(x.length);
        x = Arrays.copyOf(x, n);
        double[] y = new double[n];

        int i;
        for (i = 1; i < n; ++i) {
            y[i] = x[i];
        }

        double[] result = new double[2 * n];
        int n1 = n / 2;
        int n2 = n1 + 1;
        x = fht(x, n);

        double t;
        for (i = 1; i < n1; ++i) {
            t = x[i];
            x[i] = x[n - i];
            x[n - i] = t;
        }

        for (i = n2; i < n; ++i) {
            x[i] = -x[i];
        }

        x[0] = 0.0D;
        x[n1] = 0.0D;
        x = fht(x, n);
        t = 1.0D / (double) n;

        for (i = 0; i < n; ++i) {
            x[i] *= t;
        }

        for (i = 0; i < n; ++i) {
            result[i] = y[i];
            result[i + n] = x[i];
        }

        return result;
    }

    public static int ntom1(int n) {
        if (n < 2) {
            System.out.print("信号长度过短");
        }

        int p;
        for (p = 2; p <= n; p *= 2) {
        }

        p /= 2;
        return p;
    }

    /**
     * 峰值指标
     * x为一维数组(信号)，double[]
     * 输出结果double
     **/
    public static double CIb(double[] x) {
        double sum = 0.0D;
        int n = x.length;
        double max_1 = maxb(absb(x));

        for (int i = 0; i < n; ++i) {
            sum += x[i] * x[i];
        }

        double ci_1 = max_1 / Math.sqrt(sum / (double) n);
        return ci_1;
    }

    /**
     * 裕度指标
     * x为一维数组(信号)，double[]
     * 输出结果double
     **/
    public static double CLIb(double[] x) {
        if(x == null || x.length == 0){
            return 0;
        }
        double sum = 0.0D;
        int n = x.length;
        double max_1 = maxb(absb(x));
        for (int i = 0; i < n; ++i) {
            sum += Math.sqrt(Math.abs(x[i]));
        }
        if (sum == 0.0D || n == 0) {
            return 0.0D;
        }
        return max_1 / (sum / (double) n * (sum / (double) n));
    }

    /**
     * 脉冲指标
     * x为一维数组(信号)，double[]
     * 输出结果double
     **/
    public static double IMIb(double[] x) {
        double sum = 0.0D;
        int n = x.length;
        double max_1 = maxb(absb(x));
        for (int i = 0; i < n; ++i) {
            sum += Math.abs(x[i]);
        }
        if (sum == 0.0D || n == 0) {
            return 0.0D;
        }

        double imi_1 = max_1 / (sum / (double) n);
        return imi_1;
    }

    /**
     * 波形指标
     * x为一维数组(信号)，double[]
     * 输出结果double
     **/
    public static double SIb(double[] x) {
        double sum1 = 0.0D;
        double sum2 = 0.0D;
        int n = x.length;

        for (int i = 0; i < n; ++i) {
            sum2 += Math.abs(x[i]);
            sum1 += x[i] * x[i];
        }
        if (sum1 == 0.0D || sum2 == 0.0D || n == 0) {
            return 0.0D;
        }
        double si_1 = Math.sqrt(sum1 / (double) n) / (sum2 / (double) n);
        return si_1;
    }

    /**
     * 偏度指标
     * x为一维数组(信号)，double[]
     * 输出结果double
     **/
    public static double SKb(double[] x) {
        double sigma = stdb(x);
        int n = x.length;
        double sum = 0.0D;

        for (int i = 0; i < n; ++i) {
            sum += x[i];
        }

        double x_m = sum / (double) n;
        sum = 0.0D;

        for (int i = 0; i < n; ++i) {
            sum += (x[i] - x_m) * (x[i] - x_m) * (x[i] - x_m);
        }

        double sk_1 = sum / ((double) (n - 1) * sigma * sigma * sigma);
        return sk_1;
    }

    /**
     * 峭度指标
     * x为一维数组(信号)，double[]
     * 输出结果double
     **/
    public static double KUb(double[] x) {
        double sigma = stdb(x);
        int n = x.length;
        double sum = 0.0D;

        for (int i = 0; i < n; ++i) {
            sum += x[i];
        }

        double x_m = sum / (double) n;
        sum = 0.0D;

        for (int i = 0; i < n; ++i) {
            sum += (x[i] - x_m) * (x[i] - x_m) * (x[i] - x_m) * (x[i] - x_m);
        }

        double ku_1 = sum / ((double) (n - 1) * sigma * sigma * sigma * sigma);
        return ku_1;
    }

    public static double maxb(double[] x) {
        double max_b = x[0];

        for (int i = 0; i < x.length; ++i) {
            if (x[i] >= max_b) {
                max_b = x[i];
            }
        }

        return max_b;
    }

    public static double[] absb(double[] x) {
        double[] y = new double[x.length];

        for (int i = 0; i < x.length; ++i) {
            y[i] = Math.abs(x[i]);
        }

        return y;
    }

    public static double stdb(double[] x) {
        int n = x.length;
        double sum = 0.0D;

        for (int i = 0; i < n; ++i) {
            sum += x[i];
        }

        double x_m = sum / (double) n;
        double dVar = 0.0D;

        for (int i = 0; i < n; ++i) {
            dVar += (x[i] - x_m) * (x[i] - x_m);
        }

        double std_1 = Math.sqrt(dVar / (double) n);
        return std_1;
    }
}
